import os
import logging
import asyncio
from flask import Flask, request, jsonify
from flask_cors import CORS  # 导入 CORS
from flask_socketio import SocketIO
import threading
import time
import serial.tools.list_ports
import com_serial
import com_ble
import zq_ota
import zq_data

app = Flask(__name__)
CORS(app)  # 允许所有域名访问
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, 
                    cors_allowed_origins="*", 
                    async_mode='threading',  # 强制使用线程模式
                    # ping_interval=60,         # 设置ping间隔为60秒(默认25秒)
                    # ping_timeout=120          # 设置ping超时为120秒(默认20秒)
                    ping_interval=600,          # TODO-DEBUG设置ping间隔为60秒(默认25秒)
                    ping_timeout=600            # TODO-DEBUG设置ping超时为120秒(默认20秒)
                    )

# 配置日志
log1 = logging.getLogger('log1')
log1.setLevel(logging.INFO)
log1_handler = logging.StreamHandler()
log1_handler.setFormatter(logging.Formatter('%(asctime)s - Log1 - %(message)s'))
log1.addHandler(log1_handler)

log2 = logging.getLogger('log2')
log2.setLevel(logging.INFO)
log2_handler = logging.StreamHandler()
log2_handler.setFormatter(logging.Formatter('%(asctime)s - Log2 - %(message)s'))
log2.addHandler(log2_handler)

ble_devs = []

# 文件上传接口
@app.route('/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return jsonify({'error': '没有文件部分'}), 400
    
    file = request.files['file']
    
    if file.filename == '':
        return jsonify({'error': '没有选择文件'}), 400
    
    if (not file.filename.endswith('.img')) and (not file.filename.endswith('.bin')) and (not file.filename.endswith('.cat')):
        return jsonify({'error': '文件格式必须是img/bin/cat'}), 400
    
    try:
        # 读取HEX内容
        file_content = file.read()
        zq_data.set_ota_img(file.filename, file_content)
        
        return jsonify({'message': f'OTA文件已传输完成'}), 200
    
    except Exception as e:
        log2.error(f"处理文件时出错: {str(e)}")
        return jsonify({'error': f'处理文件时出错: {str(e)}'}), 500


# 启停串口
@app.route('/toggle_serial', methods=['POST'])
def toggle_serial():
    try:
        data = request.get_json()
        is_serial_running = data.get('is_serial_running', False)
        com_serial.ToggleSerialPort(is_serial_running)
        return jsonify({"status": "success", "is_serial_running": is_serial_running})
    except Exception as e:
        return jsonify({"status": "error", "message": str(e)}), 500

# 选择BLE
@app.route('/select-ble-dev', methods=['POST'])
def select_ble_dev():
    data = request.get_json()
    dev = data.get('dev')
    com_ble.select_dev(dev, socketio)
    # 模拟串口操作，实际可以保存到全局变量或用于后续通信
    print(f"Selected BLE device: {dev}")

    return jsonify({
        "message": f"成功选择了BLE: {dev}"
    })
# 启停BLE设备
@app.route('/toggle-ble-dev', methods=['POST'])
def ToggleBleDev():
    data = request.get_json()
    is_serial_running = data.get('is_ble_running', False)
    com_ble.ToggleBleDev(is_serial_running)

cur_dev:str = ""

# 获取串口列表
@app.route('/ports', methods=['GET'])
def get_serial_ports():
    try:
        ports = com_serial.list_serial_ports()
        return jsonify({'ports': ports})
    except Exception as e:
        return jsonify({'error': '无法获取串口列表: ' + str(e)}), 500

# 获取BLE设备列表
@app.route('/ble_devs', methods=['GET'])
def get_ble_devs():
    global ble_devs
    try:
        ble_devs = asyncio.run(com_ble.list_ble_devs(5))
        return jsonify({'devs': ble_devs})
    except Exception as e:
        return jsonify({'error': '无法获取BLE设备列表: ' + str(e)}), 500
# 启停设备
@app.route('/toggle-device', methods=['POST'])
def ToggleDevice():
    global cur_dev, recv_ack

    try:
        data = request.get_json()
        start = data.get('start', False)
        cur_dev = data.get('dev', '').upper()
        recv_ack = False
        if cur_dev.startswith("COM"):
            if start:
                com_serial.StartDev(cur_dev)
            else:
                com_serial.StopDev()

        elif cur_dev[2] == ":" and cur_dev[5] == ":" :
            if start:
                com_ble.StartDev(cur_dev)
            else:
                com_ble.StopDev()
        else:
            print("错误：未知设备")
        return jsonify({"status": "success"})
    except Exception as e:
        return jsonify({"status": "error", "message": str(e)}), 500

# SocketIO连接处理
@socketio.on('connect')
def handle_connect():
    global ble_devs
    print('服务器已连接------')
    com_serial.socket = socketio
    com_ble.socket = socketio

@socketio.on('disconnect')
def handle_disconnect():
    print("服务器已断开------")
    com_serial.socket = None
    com_ble.socket = None
    com_serial.StopDev()

if __name__ == '__main__':
    # # 启动日志生成线程
    # stop_log_thread = False
    # log_thread = threading.Thread(target=com_serial.log_thread, daemon=True)
    # log_thread.start()
    
    print('服务器启动中...')
    socketio.run(app, host='0.0.0.0', port=5000)    